home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Topik / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].zip / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].adf / MicroRayDbw / output.c < prev    next >
C/C++ Source or Header  |  1988-12-11  |  8KB  |  276 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1988, David B. Wecker            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  * This file is part of DBW_uRAY                    *
  7.  *                                    *
  8.  * DBW_uRAY is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts        *
  10.  * responsibility to anyone for the consequences of using it or for    *
  11.  * whether it serves any particular purpose or works at all, unless    *
  12.  * he says so in writing. Refer to the DBW_uRAY General Public        *
  13.  * License for full details.                        *
  14.  *                                    *
  15.  * Everyone is granted permission to copy, modify and redistribute    *
  16.  * DBW_uRAY, but only under the conditions described in the        *
  17.  * DBW_uRAY General Public License. A copy of this license is        *
  18.  * supposed to have been given to you along with DBW_uRAY so you    *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this    *
  21.  * notice must be preserved on all copies.                *
  22.  ************************************************************************
  23.  *                                    *
  24.  * Authors:                                *
  25.  *    DBW - David B. Wecker                        *
  26.  *                                    *
  27.  * Versions:                                *
  28.  *    V1.0 881023 DBW    - First released version            *
  29.  *    V1.1 881110 DBW - Fixed scan coherence code            *
  30.  *    V1.2 881125 DBW - Removed ALL scan coherence code (useless)    *
  31.  *              added "fat" extent boxes            *
  32.  *                                    *
  33.  ************************************************************************/
  34.  
  35. #include "uray.h"
  36.  
  37.  
  38. /************************************************************************/
  39. /************ module to write output files ******************************/
  40. /************************************************************************/
  41.  
  42.  
  43. void wfil(fil,cnt,val)        /* write a number to a file (68000 order) */
  44. FILE    *fil;
  45. short    cnt;
  46. char    val[];
  47.     {
  48.  
  49. #ifdef MCH_AMIGA
  50.     fwrite(val,cnt,1,fil);
  51. #else
  52.     while (cnt--) fwrite(&val[cnt],1,1,fil);
  53. #endif
  54.  
  55.     }
  56.  
  57. short rfil(fil,cnt,val)        /* read a number from a file (68000 order) */
  58. FILE    *fil;
  59. short    cnt;
  60. char    val[];
  61.     {
  62.  
  63. #ifdef MCH_AMIGA
  64.     if (fread(val,cnt,1,fil) != 1)           return(-1);
  65. #else
  66.     while (cnt--) if (fread(&val[cnt],1,1,fil) != 1) return(-1);
  67. #endif
  68.  
  69.     return(0);
  70.     }
  71.  
  72.  
  73. /* create output files */
  74. void coutputs() {
  75.     int        i;
  76.  
  77.     /* first create the output .tmp file */
  78.     if (bpp) {
  79.     sprintf(str,"%s.tmp",basnam);
  80.     fp = fopen(str,"w");
  81.     if (!fp) leave("Bad output file");
  82.  
  83.     /* write out the header */
  84.     wfil(fp,sizeof(short),&startrow);
  85.     wfil(fp,sizeof(short),&endrow);
  86.     wfil(fp,sizeof(short),&cols);
  87.     wfil(fp,sizeof(short),&bpp);
  88.     }
  89.  
  90.     /* second, create the output .ilbm file */
  91.     sprintf(str,"%s.ilbm",basnam);
  92.     fp2 = fopen(str,"w");
  93.     if (!fp2) leave("Bad output file (ilbm)");
  94.  
  95.     /* write out the header */
  96.     sprintf(str,"FORM");    fwrite(str,1,4,fp2);
  97.     pos1 = ftell(fp2);
  98.     lng = FORMsize;        wfil(fp2,sizeof(long),&lng);
  99.     sprintf(str,"ILBM");    fwrite(str,1,4,fp2);
  100.  
  101.     sprintf(str,"BMHD");    fwrite(str,1,4,fp2);
  102.     lng = BMHDsize;        wfil(fp2,4,&lng);
  103.     wrd = cols;            wfil(fp2,2,&wrd);   /* width */
  104.     wrd = rows;            wfil(fp2,2,&wrd);   /* height */
  105.     wrd = startrow;        wfil(fp2,2,&wrd);   /* top */
  106.     wrd = 0;            wfil(fp2,2,&wrd);   /* left */
  107.     byt = DEPTH;        wfil(fp2,1,&byt);   /* Depth */
  108.     byt = 0;            wfil(fp2,1,&byt);   /* mask */
  109.     byt = 1;            wfil(fp2,1,&byt);   /* compress */
  110.     byt = 0;            wfil(fp2,1,&byt);   /* pad */
  111.     wrd = 0;            wfil(fp2,2,&wrd);   /* transparency */
  112.     byt = 10;            wfil(fp2,1,&byt);   /* aspect x */
  113.     byt = 11;            wfil(fp2,1,&byt);   /* aspect y */
  114.     wrd = cols;            wfil(fp2,2,&wrd);   /* page width */
  115.     wrd = rows;            wfil(fp2,2,&wrd);   /* page height */
  116.  
  117.     sprintf(str,"CAMG");    fwrite(str,1,4,fp2);
  118.     lng = CAMGsize;        wfil(fp2,4,&lng);
  119.     lng    = HAM | LACE;        wfil(fp2,4,&lng);
  120.  
  121.     sprintf(str,"CMAP");    fwrite(str,1,4,fp2);
  122.     lng = CMAPsize;        wfil(fp2,4,&lng);
  123.     pos3 = ftell(fp2);
  124.     colors[0][0] = colors[0][1] = colors[0][2] = 0;
  125.     lstcolor      = 1;
  126.     fwrite(colors,1,48,fp2);
  127.     fwrite(colors,1,48,fp2);
  128.  
  129.     sprintf(str,"BODY");    fwrite(str,1,4,fp2);
  130.     pos2 = ftell(fp2);
  131.     lng = BODYsize;        wfil(fp2,4,&lng);
  132.  
  133.     lsize = 0L;
  134.     }
  135.  
  136. /* write a scan line to the output files */
  137. void woutputs(sline)
  138. short    sline;
  139.     {
  140.     int            i,j,k,c,d,old[3],new[3],x,pxl,scr,addok,
  141.             index,bdist,ndist,maxdist,dcol,dval;
  142.     unsigned char   buf[512],planes[6][128],b1,b2;
  143.  
  144.     /* print out 'dots' so the user knows we're working */
  145.     if (sline % 50 == 0 || sline == startrow)    
  146.                 printf("Row %4d: ",sline);
  147.     printf(".");
  148.     if (sline % 50 == 49)   printf("\n");
  149.     else            fflush(stdout);
  150.  
  151.     /* write out a scan line to .tmp file */
  152.     if (bpp) {
  153.     wfil(fp,sizeof(short),&sline);
  154.  
  155.     /* now write out each color of the scan line */
  156.     for (i=0; i<3; i++) {
  157.  
  158.         /* write out 24 bits per pixel */
  159.         if (cols == obpsl) fwrite(outary[i],1,obpsl,fp);
  160.  
  161.         /* or 12 bits per pixel (need to pack it) */
  162.         else {
  163.         for (x=0; x<cols; x++) {
  164.             b1   = outary[i][x];
  165.             b2   = b1 >> 4;
  166.             if (x & 1)    buf[x>>1] |= b2 & 0x0F;
  167.             else    buf[x>>1]  = b1 & 0xF0;
  168.             }
  169.         fwrite(buf,1,obpsl,fp);
  170.         }
  171.         }
  172.     fflush(fp);
  173.     }
  174.  
  175.     /* initialize the HAM encoding */
  176.     for (i=0; i<3; i++) old[i] = 0;
  177.     for (d=0; d<6; d++)
  178.     for (i=0; i<MAXBYTE; i++)
  179.         planes[d][i] = 0;
  180.  
  181.     /* allow 1 new color to be added to colors[] per scan line (max) */
  182.     addok = 1;
  183.  
  184.     /* set the amount of error for adding new colors[] */
  185.     if (sline < (rows>>1))  maxdist = 127;
  186.     else            maxdist = 63;
  187.  
  188.     for (x=0; x<cols; x++,dcol++) {
  189.  
  190.     /* first get the desired old values (dither as necessary) */
  191.     for (i=0; i<3; i++) {
  192.         dval    = ((int)outary[i][x]) & 0xF;
  193.         new[i]  = ((int)outary[i][x]) & 0xF0;
  194.         if (dval && new[i] != 0xF0 && dval > (random() & 0xF))
  195.         new[i] += 0x10;
  196.         }
  197.  
  198.     /* get the best absolute color */
  199.     bdist = 9999;
  200.     for (i=0; i<lstcolor; i++) {
  201.         ndist = 0;
  202.         for (j=0; j<3; j++) 
  203.         ndist += ABS(new[j] - (int)colors[i][j]);
  204.         if (ndist < bdist) {
  205.         bdist = ndist;
  206.         index = i;
  207.         }
  208.         }
  209.  
  210.     /* now find worst color (to make relative change) */
  211.     ndist = 0;
  212.     j     = -1;
  213.     for (i = 0; i<3; i++) {
  214.         if ((k=ABS(new[i] - old[i])) > j) { 
  215.         c   = i; 
  216.         j   = k;
  217.         }
  218.         ndist += k;
  219.         }
  220.  
  221.     /* subtract off the gun we want to fix */
  222.     ndist -= j;
  223.  
  224.     /* if relative is best, flag it (index = -1) (unless first pixel) */
  225.     if (x > 0 && ndist < bdist) {
  226.         bdist = ndist;
  227.         index = -1;
  228.         }
  229.  
  230.     /* decide if we need a new color in the color table */
  231.     if (addok && lstcolor < 16 && bdist > maxdist) {
  232.         for (i=0; i<3; i++) colors[lstcolor][i] = (unsigned char)new[i];
  233.         addok = 0;
  234.         bdist = 0;
  235.         index = lstcolor++;
  236. #        if DEBUG_ilbm
  237.         printf("Adding color %2d: %02x%02x%02x\n",index,
  238.             new[0],new[1],new[2]);
  239. #        endif
  240.         }
  241.  
  242.     /* now change the gun (for relative) */
  243.     if (index == -1) {
  244.         pxl = (old[c] = new[c]) >> 4;
  245.         switch (c) {
  246.         case 0: pxl |= 0x20;  break;
  247.         case 1: pxl |= 0x30;  break;
  248.         case 2: pxl |= 0x10;  break;
  249.         }
  250.         }
  251.     else {
  252.         pxl = index;
  253.         for (i=0; i<3; i++) old[i] = (int)colors[index][i];
  254.         }
  255.  
  256. #    if DEBUG_ilbm
  257.         printf("%4d,%4d: %02x (%d)\n",sline,x,pxl,bdist);
  258. #        endif
  259.  
  260.     /* and store the pixel away */
  261.     j = x >> 3;
  262.     k = 7 - (x & 0x7);
  263.     for (i=0; i<DEPTH; i++) {
  264.         planes[i][j] |= (pxl & 1) << k;
  265.         pxl >>= 1;
  266.         }
  267.     }
  268.  
  269.     /* now pack the row away (RKM run length encoding) */
  270.     for (i=0; i < DEPTH; i++) {
  271.     wrd    = PackRow(planes[i],buf,MAXBYTE);
  272.     lsize += (long)wrd;
  273.     fwrite(buf,1,wrd,fp2);
  274.     }
  275.     }
  276.